package com.xr.blackhoole.autoconfigurer.datasource.mybatis;

import com.xr.blackhoole.datasource.BlackholeDynamicDataSource;
import com.xr.blackhoole.datasource.DynamicDataSourceContextHolder;
import org.apache.commons.lang3.StringUtils;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.HashMap;

@ConditionalOnClass({SqlSessionFactoryBean.class})
@ConditionalOnBean(name = {"primaryDatasource", "shadowDatasource"})
@Configuration
public class BlackholeMybatisConfiguration {

    @Resource(name = "primaryDatasource")
    private DataSource primary;
    @Resource(name = "shadowDatasource")
    private DataSource shadow;

    @Value("${mybatis.mapper-locations}")
    private String mapperLocations;

    @Value("${mybatis.type-aliases-package}")
    private String typeAliasesPackage;

    @Bean("dynamicDataSource")
    public DataSource dynamicDataSource() {
        BlackholeDynamicDataSource dynamicDataSource = new BlackholeDynamicDataSource();
        HashMap<Object, Object> dataSourceMap = new HashMap<>(2);
        dataSourceMap.put(DynamicDataSourceContextHolder.PRIMARY_DB, primary);
        dataSourceMap.put(DynamicDataSourceContextHolder.SHADOW_DB, shadow);

        //将master 数据源作为默认的指定数据源
        dynamicDataSource.setDefaultDataSource(primary);
        dynamicDataSource.setDataSources(dataSourceMap);
        return dynamicDataSource;
    }

    @Bean
    public SqlSessionFactoryBean sqlSessionFactoryBean() throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        // 配置数据源，此处配置为关键配置，如果没有将 dynamicDataSource作为数据源则不能实现切换
        sqlSessionFactoryBean.setDataSource(dynamicDataSource());
        if (StringUtils.isNotEmpty(typeAliasesPackage)) {
            sqlSessionFactoryBean.setTypeAliasesPackage(typeAliasesPackage);
        }
        
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sqlSessionFactoryBean.setMapperLocations(resolver.getResources(mapperLocations));    // 扫描映射文件

        return sqlSessionFactoryBean;
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        // 配置事务管理, 使用事务时在方法头部添加@Transactional注解即可
        return new DataSourceTransactionManager(dynamicDataSource());
    }
}
